package cn.edu.xmist;

import cn.edu.xmist.tank.AbstractTank;
import cn.edu.xmist.tank.EnemyTank;
import cn.edu.xmist.tank.P1Tank;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class GameFrame extends Frame {

    /**
     * 定义游戏界面的宽
     */
    private static final int WIDTH = 1000;

    /**
     * 定义游戏界面的高度
     */
    private static final int HEIGHT = 600;

    /**
     * 定义游戏界面的标题
     */
    private static final String TITLE = "坦克大战";

    /**
     * 我方坦克
     */
    private final AbstractTank tank = new P1Tank(this);

    /**
     * 敌方坦克1
     */
    private final AbstractTank enemy1Tank = new EnemyTank(this);

    /**
     * 缓冲画板
     */
    private BufferedImage memoryBufferImage;

    public GameFrame() throws HeadlessException {
        this.setResizable(false);
        this.setTitle(TITLE);
        this.setSize(WIDTH, HEIGHT);

        /**
         * 默认窗口不可以关闭，点击窗口胡关闭按钮时，以事件机制通知，执行退出游戏
         */

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        this.addKeyListener(new KeyAdapter() {
            /**
             * 键盘按下事件
             * @param e
             */
            @Override
            public void keyPressed(KeyEvent e) {
                int keyCode = e.getKeyCode();
                switch (keyCode) {
                    case KeyEvent.VK_UP:
                        GameFrame.this.tank.startMoveUp();
                        break;
                    case KeyEvent.VK_DOWN:
                        GameFrame.this.tank.startMoveDown();
                        break;
                    case KeyEvent.VK_LEFT:
                        GameFrame.this.tank.startMoveLeft();
                        break;
                    case KeyEvent.VK_RIGHT:
                        GameFrame.this.tank.startMoveRight();
                        break;
                }
            }

            /**
             * 键盘放开事件
             * @param e
             */
            @Override
            public void keyReleased(KeyEvent e) {
                int keyCode = e.getKeyCode();
                switch (keyCode) {
                    case KeyEvent.VK_UP:
                        GameFrame.this.tank.stopMoveUp();
                        break;
                    case KeyEvent.VK_DOWN:
                        GameFrame.this.tank.stopMoveDown();
                        break;
                    case KeyEvent.VK_LEFT:
                        GameFrame.this.tank.stopMoveLeft();
                        break;
                    case KeyEvent.VK_RIGHT:
                        GameFrame.this.tank.stopMoveRight();
                        break;
                    case KeyEvent.VK_CONTROL:
                        GameFrame.this.tank.fire();
                        break;
                }
            }
        });

        /**
         * 当我们修改位置或形态的时候，画板需要重新渲染，所以我们需要定义一个定时器、
         * 每隔一段时间，重新渲染
         */

        new Thread(
                ()->{
                    /**
                     * 不停的执行
                     */
                    while (true) {
                        try {
                            Thread.sleep(30);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        /**
                         * 画板重新渲染
                         */
                        this.repaint();
                    }
                }
        ).start();


        /**
         * ==========================敌方坦克
         */

        Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(()->{
            /**
             * directions集合存放所有的方向(临时)
             */
            HashSet<Direction> currentDirections = new HashSet<>(Arrays.asList(Direction.values()));

            if (this.enemy1Tank.getX() >= WIDTH -60) {
                /**
                 * 已经到最右边
                 */
                currentDirections.remove(Direction.RIGHT);
            }else if (this.enemy1Tank.getX() < 60) {
                /**
                 * 已经到最左边
                 */
                currentDirections.remove(Direction.LEFT);
            }else if (this.enemy1Tank.getY() < 60) {
                /**
                 * 已经到最上边
                 */
                currentDirections.remove(Direction.UP);
            }else if (this.enemy1Tank.getY() >= HEIGHT - 60) {
                /**
                 * 已经到最上边
                 */
                currentDirections.remove(Direction.DOWN);
            }


            /**
             * 随机一个方向
             */
            ArrayList<Direction> directionArr = new ArrayList<>();
            directionArr.addAll(currentDirections);

            /**
             * 通过shuffle打乱方向的顺序
             */
            Collections.shuffle(directionArr);

            Direction direction = directionArr.get(0);

            switch (direction) {
                case UP:
                    GameFrame.this.enemy1Tank.startMoveUp();
                    break;
                case DOWN:
                    GameFrame.this.enemy1Tank.startMoveDown();
                    break;
                case LEFT:
                    GameFrame.this.enemy1Tank.startMoveLeft();
                    break;
                case RIGHT:
                    GameFrame.this.enemy1Tank.startMoveRight();
                    break;
            }


        }, 10, 300, TimeUnit.MILLISECONDS);

    }

    /**
     * 显示坦克
     * @param g
     */
    @Override
    public void paint(Graphics g){
        this.tank.paint(g);
        this.enemy1Tank.paint(g);
    }

    @Override
    public void update(Graphics g) {
        if (this.memoryBufferImage == null) {
            this.memoryBufferImage = (BufferedImage) this.createImage(WIDTH, HEIGHT);
        }

        Graphics graphics = this.memoryBufferImage.getGraphics();

        Color color = graphics.getColor();

        /**
         * 黑色的画笔
         */
        graphics.setColor(Color.BLACK);

        /**
         * 填充了背景色
         */
        graphics.fillRect(0, 0, WIDTH, HEIGHT);

        graphics.setColor(color);

        this.paint(graphics);

        /**
         * 画制面板
         */
        g.drawImage(this.memoryBufferImage, 0, 0, null);

    }
}
